package com.cardone.common.annotation.support;

import com.cardone.common.annotation.RunAction;
import com.cardone.context.ContextHolder;
import com.cardone.context.action.Run3Action;
import com.cardone.context.function.Execution2Function;
import com.cardone.context.function.Execution3Function;
import com.google.common.collect.Maps;
import lombok.Getter;
import lombok.Setter;

import java.util.Map;

/**
 * Created by Administrator on 2015/3/23.
 */
public abstract class AfterRunActionSupport implements Run3Action<RunAction, Object[], Object> {
    protected Map<String, Object> newParameterMap(RunAction runAction) {
        String message = this.getReadDictionaryValueFunction().execution(runAction.afterMessage(), runAction.afterTypeCode(), runAction.afterCode());

        Map<String, Object> parameterMap = Maps.newHashMap();

        parameterMap.put("message", message);

        return parameterMap;
    }
    @Setter
    @Getter
    private Execution3Function<String, String, String, String> readDictionaryValueFunction;

    protected Map<String, Object> getInputParameterMap(String inputParameterBeanId, Map<String, Object> parameterMap, Object[] args) {
        Object inputParameterBeanObject = ContextHolder.getBean(inputParameterBeanId);

        if (inputParameterBeanObject == null) {
            return parameterMap;
        }

        if (!(inputParameterBeanObject instanceof Execution2Function)) {
            return parameterMap;
        }

        Execution2Function<Map<String, Object>, Map<String, Object>, Object[]> inputParameterBean = (Execution2Function<Map<String, Object>, Map<String, Object>, Object[]>) inputParameterBeanObject;

        return inputParameterBean.execution(parameterMap, args);
    }

    protected Map<String, Object> getOutputParameterMap(String outputParameterBeanId, Map<String, Object> parameterMap, Object returnData) {
        Object outputParameterBeanObject = ContextHolder.getBean(outputParameterBeanId);

        if (outputParameterBeanObject == null) {
            return parameterMap;
        }

        if (!(outputParameterBeanObject instanceof Execution2Function)) {
            return parameterMap;
        }

        Execution2Function<Map<String, Object>, Map<String, Object>, Object> outputParameterBean = (Execution2Function<Map<String, Object>, Map<String, Object>, Object>) outputParameterBeanObject;

        return outputParameterBean.execution(parameterMap, returnData);
    }

    protected Map<String, Object> getParameterMap(RunAction runAction, Object[] args, Object returnData) {
        Map<String, Object> parameterMap = this.newParameterMap(runAction);

        parameterMap = this.getInputParameterMap(runAction.inputParameterBeanId(), parameterMap, args);

        return this.getOutputParameterMap(runAction.outputParameterBeanId(), parameterMap, returnData);
    }

    @Override
    public void run(RunAction runAction, Object[] objects, Object returnData) {
        Map<String, Object> parameterMap = this.getParameterMap(runAction, objects, returnData);

        this.run(runAction, parameterMap);
    }

    protected abstract void run(RunAction runAction, Map<String, Object> parameterMap);
}
